#include "neiku/json_serialize.h"
#include "neiku/log.h"
#include "neiku/utility.h"
#include "neiku/render.h"
#include "neiku/tsm.h"

using namespace neiku;

// 处理器生成工厂方法池
std::map<std::string, ProcessorBuilderFn>& neiku::ProcessorBuilers()
{
    static std::map<std::string, ProcessorBuilderFn> fns;
    return fns;
}

// 处理器生成工厂方法，方便动态生成处理器
Processor* neiku::NewProcessor(const std::string& name, const std::string& body)
{
    ProcessorBuilderFn build = ProcessorBuilers()[name];
    if (build) {
        return build(body);
    }
    return NoopProcess::build(body);
}

// 从json恢复
int TSM::recover(const std::string& body)
{
    // 重置
    processor_cursor = 0;
    in.clear();
    out.clear();
    processors.clear();

    // 恢复
    return json_decode(body, *this);
}

// 执行任务
int TSM::process()
{
    // 初始输入
    if (processor_cursor == 0) {
        out = in;
    }
    // 从断点开始
    for (;processor_cursor < processors.size(); processor_cursor++) {
        TSMProcessor& tp = processors[processor_cursor];

        // 当前处理器的输入就是上次的输出
        tp.in = out;
        // 清空上次输出，执行本次任务并获得最新输出
        out.clear();
        int ret = tp.processor->process(tp.in, out);
        if (ret != 0) {
            // 执行失败，则恢复上次输出到当前的输入，保存可重入
            out = tp.in;
            return ret;
        }
        // 执行成功，记录当前任务输出结果
        tp.out = out;
    }
    return 0;
}

int NoopProcess::process(const neiku::data_t& in, neiku::data_t& out)
{
    out = in;
    return 0;
}

std::string neiku::data_get(const data_t& d, const std::string& k, bool* ok)
{
    data_t::const_iterator it = d.find(k);
    if (it != d.end()) {
        if (ok) { *ok = true; }
        return it->second;
    }

    if (ok) { *ok = false; }
    return "";
}
